package com.example.dayu521.sg_oss.service.impl;

import com.example.dayu521.sg_oss.conf.prop.LocalFilePro;
import com.example.dayu521.sg_oss.service.BaseServiceProvider;
import com.example.dayu521.sg_oss.service.Oss;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.example.dayu521.exception.DuplicateOssObj;
import org.example.dayu521.exception.NoSuchOss;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Arrays;

@Service
@ConditionalOnProperty(prefix = "sg.oss", name = "backend", havingValue = "local", matchIfMissing = false)
@EnableConfigurationProperties({LocalFilePro.class})
@Slf4j
public class LocalFileOss implements Oss {

    @Autowired
    public void setLocalFilePro(LocalFilePro localFilePro) {
        this.localFilePro = localFilePro;
    }

    @PostConstruct
    public void init() {
        File file = new File(localFilePro.getDir());
        if (!file.mkdir()) {
            if (!file.exists()) {
                throw new RuntimeException(String.format("upload:%s目录创建失败", localFilePro.getDir()));
            }
        }
        log.info("创建目录{}成功", localFilePro.getDir());


    }

    private LocalFilePro localFilePro;

    @Override
    public void put_obj(String obj_name, InputStream obj_src, long obj_size) throws DuplicateOssObj {

        var file = new File(localFilePro.getDir() + "/" + obj_name);
        boolean cf_ok = false;
        try {
            cf_ok = file.createNewFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (cf_ok == false) {
            throw new DuplicateOssObj("脏文件存在,后台将会清除异常文件.稍后再试",null);
        }
        try (var out = new BufferedOutputStream(new FileOutputStream(file))) {
            final byte[] buff = new byte[1024];
            int nbyte = 0;
            while ((nbyte = obj_src.read(buff)) == buff.length) {
                out.write(buff);
            }
            if (nbyte > 0) {
                out.write(Arrays.copyOf(buff, nbyte));
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public InputStream get_obj(String obj_name) throws NoSuchOss {
        InputStream in = InputStream.nullInputStream();
        try {
            in = Files.newInputStream(Path.of(localFilePro.getDir() + "/" + obj_name));
        } catch (IllegalArgumentException e) {
            log.error("参数错误{}",localFilePro.getDir() + "/" + obj_name);
        }catch (NoSuchFileException e){
            throw new NoSuchOss(e);
        }
        catch (IOException e) {
            log.error("Files.newInputStream调用出错,参数{}", localFilePro.getDir() + "/" + obj_name);
            throw new RuntimeException(e);
        }
        return in;
    }

    @Override
    public boolean rm_obj(String obj_name) {
        try {
            return Files.deleteIfExists(Path.of(localFilePro.getDir() + "/" + obj_name));
        }  catch (DirectoryNotEmptyException e) {
            log.error("目标是一个目录,且不为空,删除失败:{}", obj_name);
            return false;
        } catch (IOException e) {
            log.error("删除文件异常:{}", obj_name);
            throw new RuntimeException(e);
        }
    }

    @Override
    public String oss_identify() {
        return "local";
    }

    @Override
    public void ask_for_help(BaseServiceProvider baseServiceProvider) {
        baseServiceProvider.locale(this);
    }
}
